# coding=utf-8
"""
    @project: qabot
    
    @file： team_serializers.py
    @date：2023/9/5 16:32
    @desc:
"""


from django.core import validators, signing, cache
from django.db.models import Q, QuerySet
from drf_yasg import openapi
from rest_framework import serializers
from users.models.user import User
import requests
import json
import uuid
from common.mixins.api_mixin import ApiMixin
from django.utils.translation import gettext_lazy as _
from xpack.models import AuthConfig
from xpack.models import UserAuth
from common.constants.authentication_type import AuthenticationType
from smartdoc.settings import JWT_AUTH
from wechatpy.work import WeChatClient
from common.constants.permission_constants import RoleConstants
user_cache = cache.caches['user_cache']

token_cache = cache.caches['token_cache']

class AuthConfigSerializer(ApiMixin, serializers.ModelSerializer):
    class Meta:
        model = AuthConfig
        fields = ["platform", "id", "config", "create_time", "update_time","is_valid","is_active"]

    def get_response_body_api(self):
        return openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=["platform", "id", "config", "user_id", "create_time", "update_time"],
            properties={
                'id': openapi.Schema(type=openapi.TYPE_STRING, title="ID", description="ID"),
                'platform': openapi.Schema(type=openapi.TYPE_STRING, title=_("Username"), description=_("Username")),
                'user_id': openapi.Schema(type=openapi.TYPE_STRING, title=_("Email"), description=_("Email")),
                'config': openapi.Schema(type=openapi.TYPE_STRING, title=_("Role"), description=_("Role"))
            }
        )
    class Create(serializers.Serializer):
        user_id = serializers.UUIDField(required=True)
        platform = serializers.CharField(required=True)
        content = serializers.JSONField(required=True)
        isActive = serializers.BooleanField(required=False, default=False)
        isValid = serializers.BooleanField(required=True)
        def save(self, with_valid=True):
            if with_valid:
                self.is_valid(raise_exception=True)
            data = {
                'platform': self.data.get('platform'),
                'user_id': self.data.get('user_id'),
                'config': self.data.get('content'),
                'is_active': self.data.get('isActive'),
                'is_valid': self.data.get('isValid')
            }
            info = QuerySet(AuthConfig).filter(user_id=data['user_id'], platform=data['platform']).first()
            if info:
                QuerySet(AuthConfig).filter(id=info.id).update(**data)
            else:
                QuerySet(AuthConfig).create(**data)
            return data
    class Query(ApiMixin, serializers.Serializer):
        platform = serializers.CharField(required=True)
        def info(self, with_valid=True):
            if with_valid:
                self.is_valid(raise_exception=True)
            platform = self.data.get('platform')
            info = QuerySet(AuthConfig).filter(platform=platform).first()
            if not info:
                return None
            return info
    
    class Source(ApiMixin, serializers.Serializer):
        user_id = serializers.UUIDField(required=False)
        platform = serializers.CharField(required=False)
        def list(self, with_valid=True):
            if with_valid:
                self.is_valid(raise_exception=True)
            list = QuerySet(AuthConfig).filter(platform__in=['wecom','lark','dingtalk']).all()
            return AuthConfigSerializer(instance=list,many=True)
class AuthLoginSerializer(ApiMixin, serializers.Serializer):
    class Wecom(ApiMixin, serializers.Serializer):
        code = serializers.CharField(required=True)
        def info(self, with_valid=True):
            if with_valid:
                self.is_valid(raise_exception=True)
            where = {
                "platform": "wecom",
            }
            wecomInfo = AuthConfigSerializer.Query(data = where).info()
            wecomConfig = wecomInfo.config
            print('企业 微信',self.data)
            client = WeChatClient(wecomConfig['corp_id'], wecomConfig['app_secret'])
            oauthUser = client.oauth.get_user_info(self.data['code'])
            print('会员 信息', oauthUser)
            openId = ""
            unionId = ""
            if 'UserId' in oauthUser:
                openId = oauthUser['UserId']
            #判断当前用户是否存在
            authUser = QuerySet(UserAuth).filter(open_id=openId, platform="wecom").first()
            userId = ""
            if authUser is not None:
                userId = authUser.user_id
            else:
                userId = uuid.uuid1()
                User(id=userId, 
                        email="",
                        phone="",
                        nick_name="",
                        username=openId,
                        password="",
                        role=RoleConstants.USER.name, 
                        source="LOCAL",
                        language="zh-CN",
                        is_active=True).save()
                authData = {
                    "user_id": userId,
                    "open_id": openId,
                    "union_id": unionId,
                    "platform": "wecom",
                    "content": {
                        "userId": "hello"
                    }
                }
                UserAuth(**authData).save()
            
            user = QuerySet(User).filter(id=userId).first()
            token = signing.dumps({'username': user.username, 'id': str(user.id), 'email': user.email,
                               'type': AuthenticationType.USER.value})
            token_cache.set(token, user, timeout=JWT_AUTH['JWT_EXPIRATION_DELTA'])
            data = {
                "token": token
            }
            return data
    class Dingtalk(ApiMixin, serializers.Serializer):
        code = serializers.CharField(required=True)
        def info(self, with_valid=True):
            if with_valid:
                self.is_valid(raise_exception=True)
            where = {
                "platform": "dingtalk",
            }
            dingtalkInfo = AuthConfigSerializer.Query(data = where).info()
            dingtalkConfig = dingtalkInfo.config
            print('钉钉',dingtalkConfig)
            postData = {
              "clientId" : dingtalkConfig['app_key'],
              "clientSecret" : dingtalkConfig['app_secret'],
              "code" : self.data.get('code'),
              "grantType" : "authorization_code"
            }
            print('钉钉',postData)
            tokenUrl = "https://api.dingtalk.com/v1.0/oauth2/userAccessToken"
            responseToken = requests.post(tokenUrl, json=postData)
            print('TOken信息', responseToken.content)
            tokenInfo = json.loads(responseToken.content)
            headers = {'x-acs-dingtalk-access-token': tokenInfo['accessToken']}
            userTokenUrl = "https://api.dingtalk.com//v1.0/contact/users/me"
            responseUser = requests.get(userTokenUrl,headers=headers)
            oauthUser = json.loads(responseUser.content)
            print('会员 信息', oauthUser)
            #会员 信息 {'nick': '李孟琦', 'unionId': 'YkiizaUcrv8AK4YRIDygCiPAiEiE', 'openId': 'JYsX3No9a9qxMJVG2hYfFAiEiE', 'mobile': '13720984421', 'stateCode': '86', 'visitor': False}
            openId = ""
            unionId = ""
            mobile = ""
            nickName = ""
            if 'openId' in oauthUser:
                openId = oauthUser['openId']
                unionId = oauthUser['unionId']
                nickName = oauthUser['nick']
                mobile = oauthUser['stateCode'] + " " + oauthUser['mobile']
            #判断当前用户是否存在
            authUser = QuerySet(UserAuth).filter(open_id=openId, platform="dingtalk").first()
            userId = ""
            if authUser is not None:
                userId = authUser.user_id
            else:
                userId = uuid.uuid1()
                User(id=userId, 
                        email="",
                        phone=mobile,
                        nick_name=nickName,
                        username=nickName,
                        password="",
                        role=RoleConstants.USER.name, 
                        source="SCAN",
                        language="zh-CN",
                        is_active=True).save()
                authData = {
                    "user_id": userId,
                    "open_id": openId,
                    "union_id": unionId,
                    "platform": "dingtalk",
                    "content": {
                        "userId": ""
                    }
                }
                UserAuth(**authData).save()
            
            user = QuerySet(User).filter(id=userId).first()
            token = signing.dumps({'username': user.username, 'id': str(user.id), 'email': user.email,
                               'type': AuthenticationType.USER.value})
            token_cache.set(token, user, timeout=JWT_AUTH['JWT_EXPIRATION_DELTA'])
            data = {
                "token": token
            }
            return data
   
